﻿/*!
 * Copyright 2011 Guangzhou Donghong Software Technology Inc.
 * Licensed under the www.jxstar.org
 */

JxLabelDes = {
	//当前方案id
	caseId: '',
	//档案设计器面板
	designCt: null,
	//标记当前选择的控件
	currCtl: null,
	//当前模板ID
	currModelId: '',
	//当前模板信息
	currRec: null,
	//布局元素ID序号，创建控件时用
	compnum: 0,
	//记录设计面板中所有的元素的DD对象，关闭页面时销毁
	designDDs: [],
	//记录设计面板中所有的元素的Resize对象，关闭页面时销毁
	designResizes: [],
	//约定1mm = 4px; 1in = 2.54cm = 25.4mm = 72pt = 96px 
	PN: 4,

	/**
	* 创建页面对象，布局：标签模板列表 + 设计器 + 字段列表 + 属性列表
	* 
	* caseId：方案ID
	* target：功能对象显示的布局
	*/
	showDesign: function(caseId, target) {
		var self = this;
		this.caseId = caseId;
		
		var tbar = self.createTool();
		var designCt = new Ext.Panel({
			border:false,
			layout:'border',
			tbar:tbar,
			items:[{
				width:140,
				//title:jx.bus.text15,//'挑选字段、模板',
				border:false,
				region:'west',
				layout:'border',
				items:[{//显示标签字段
					region:'center',
					layout:'fit'
				},{//显示打印模板列表
					region:'south',
					height:250,
					layout:'fit'
				}]
			},{//显示标签设计器
				region:'center',
				layout:'border',
				id: 'des_card_panel',
				bodyStyle:'border-left:2px solid #333;',
				items:[{
					region:'center',
					layout:'absolute',
					bodyStyle:'background-color:#6E6E6E;',
					items:[{
						id: 'des_carder',
						x: 50,
						y: 50,
						width: 400,
						height: 200,
						xtype: 'box',
						hidden: true,
						cls: 'fdes-card',
						style:'background-color:#FFF;'
					}]
				},{					
					id: 'status_bar',
					region:'south',
					height:22,
					xtype: 'box',
					style:'background-color:#E6E6E6;text-align:center;'
				}]
			},{
				region:'east',
				width:40,
				layout: {
					type:'vbox',
					padding:'1',
					align:'stretch'
				},
				cls:'dc_tool',
				bodyStyle:'background-color:#333;',
				defaults:{margins:'5 0 5 0', height:28},
				items:[{
					xtype:'button',
					iconCls:'ctl_txt',
					tooltip:jx.bus.text17,//'文本',
					handler:function(){
						self.addText(20,2,80,22, {title:jx.bus.text17, type:'label'}, true);
					}
				},{
					xtype:'button',
					iconCls:'ctl_barcode',
					tooltip:jx.bus.text18,//'条码',
					handler:function(){
						self.addBarCode(30,2,119,54.6, {title:'1234567890', type:'barcode'}, true);
					}
				},{
					xtype:'button',
					scale:'medium',
					iconCls:'ctl_qr',
					tooltip:'QR Code',
					handler:function(){
						self.addBarCode(30,2,80,80, {title:'1234567890', type:'qrcode'}, true);
					}
				},{
					xtype:'button',
					iconCls:'ctl_line',
					tooltip:jx.bus.text22,//'线条',
					handler:function(){
						alert('暂不支持线条！');
						//self.addLine(20,2,80,22,'line',null,true);
					}
				},{
					xtype:'button',
					iconCls:'ctl_image',
					tooltip:jx.bus.text23,//'图片',
					handler:function(){
						self.addImage(20,2,80,22,'image',null,true);
					}
				}]
			}]
		});
		
		var desgrid = designCt.getComponent(0);
		Jxstar.createPage('lab_field1', 'gridpage', desgrid.getComponent(0), {pageType:'notool'});
		Jxstar.createPage('lab_model1', 'gridpage', desgrid.getComponent(1), {pageType:'notool'});
				
		var tabid = 'jxstar_label_design';
		var mainTab = Jxstar.sysMainTab;
		var funTab = mainTab.getComponent(tabid);
		if (funTab != null) {
			mainTab.remove(funTab, true);
			funTab = null;
		}
		//显示数据
		funTab = mainTab.add({
				id: tabid,
				label: jx.bus.text24,//'标签设计器',
				border: false,
				layout: 'fit',
				closable: true,
				iconCls: 'tab_des',
				items: [designCt]
			});
		mainTab.activate(funTab);
		
		//模板、字段加载数据
		var hd = function() {
			var gridm = desgrid.getComponent(1).getComponent(0);
			var gridf = desgrid.getComponent(0).getComponent(0);
			
			Jxstar.loadSubData(gridm, caseId);
			Jxstar.loadSubData(gridf, caseId);
					
			//点击模板记录，加载最新的设计文件
			gridm.on('rowclick', function(g, n, e){
				var rec = g.getStore().getAt(n);
				var modelId = rec.get('lab_model__model_id');
				self.currModelId = modelId;
				self.currRec = rec;
				self.readXML(modelId);
			});
			
			//单击字段，添加字段标签到设计器中
			gridf.on('rowclick', function(g, n, e){
				var rec = g.getStore().getAt(n);
				self.addFieldLabel(rec);
			});
			
			gridm.getStore().on('load', function(){
				gridm.getSelectionModel().selectFirstRow();
				gridm.fireEvent('rowclick', gridm, 0);
			});
		};
		//保证附加事件成功
		var callhd = function() {
			var gm = desgrid.getComponent(0).getComponent(0);
			if (gm) {
				hd();
			} else {
				JxUtil.delay(200, callhd);
			}
		};
		callhd();
		
		self.statusBar = Ext.getCmp('status_bar').el;
		self.parentCmp = Ext.getCmp('des_carder');
		self.parentEl = self.parentCmp.el;
		//双击时显示属性设置
		//self.parentEl.on('dblclick', function(){self.updateProp(self.parentEl);});
		//显示初始卡片大小
		self.showCard(400, 200);
		
		//支持调整卡片大小与显示位置
		self.resizEl = null;
		var pid = self.parentEl.id;
		//new Ext.dd.DD(pid);
		self.parentEl.on('click', function(){
			if (!self.resizEl) {
				self.resizEl = new Ext.Resizable(pid, {minWidth:40, minHeight:20});
				self.resizEl.on('resize', function(el, w, h){self.showCard(w, h);});
			}
		});
		
		//删除控件
		var body = Ext.getBody();
		var delfn = function(e) {
			if (e.getKey() == 46) {
				self.deleteComp();
			}
		};
		body.on('keydown', delfn);
		//销毁临时对象
		self.parentCmp.on('beforedestroy', function(){
			self.destroy();
			//移除删除事件
			body.un('keydown', delfn);
			return true;
		});
		
		self.designCt = designCt;
	},
	
	//显示卡片大小
	showCard: function(width, height) {
		var self = this;
		var parent = Ext.getCmp('des_card_panel');
		var s = parent.getSize();
		
		var x = parseInt((s.width-width)/2);
		var y = parseInt((s.height-height)/2);
		self.parentCmp.setSize(width, height);
		self.parentCmp.setPosition(x, y);
		
		self.parentCmp.show();
	},
	
	//创建工具栏
	createTool: function() {
		var self = this;
		var tbar = new Ext.Toolbar({
			items:[
				{iconCls:'eb_save', text:jx.bus.text29, handler:function(){//保存
					if (Ext.isEmpty(self.currModelId)) {
						JxHint.alert(jx.bus.text14);//请先创建或选择标签打印模板！
						return;
					}
					self.saveXML(self.currModelId);
				}},
				{iconCls:'eb_code', text:jx.bus.text27, handler:function(){//代码
					self.showXML(self.currModelId);
				}},
				{iconCls:'eb_cog', text:'设置', handler:function(){//设置
					self.updateProp(self.parentEl);
				}},
				'->',
				{xtype: 'tbtext', text: '双击可以设置属性'}
			]
		});
		return tbar;
	},
	
	//读取设计信息
	readXML: function(modelId) {
		var self = this;
		var hdcall = function(data) {
			if (Ext.isEmpty(data)) return;
			
			self.destroy();
			self.parentEl.dom.innerHTML = '';
			//初始化控件ID序号
			self.compnum = 0;
			
			var xml = data.setxml;
			if (!xml || xml.length == 0) return;
			
			var xdoc = Request.loadXML(xml);
			//XML数据格式正确性判断
			var dom = xdoc.getElementsByTagName("page").item(0);
			if (!dom) {
				alert('XML data ['+ xml +'] format error!');
				return;
			}
			
			//显示初始卡片大小
			var width = self.readAttrFloat(dom, 'width', 100);
			var height = self.readAttrFloat(dom, 'height', 50);
			var title = self.readAttrVal(dom, 'title');
			self.showCard(width, height);
			self.parentEl.dom.setAttribute('title', title);
			
			self.parseItemXML(dom);
			
			//把元素添加到页面中
			self.insertCompHtml();
		};
		
		var params = 'funid=lab_case&eventcode=readxml&modelid='+modelId;
		Request.postRequest(params, hdcall);
	},
	
	//解析页面模板XML信息
	parseItemXML: function(dom) {
		var self = this;
		var doms = dom.getElementsByTagName("item");

		//生成每个item控件
		for (var i = 0, n = doms.length; i < n; i++) {
			var node = doms.item(i);
			var x = self.readAttrFloat(node, 'x', 10);
			var y = self.readAttrFloat(node, 'y', 10);
			var w = self.readAttrFloat(node, 'width', 50);
			var h = self.readAttrFloat(node, 'height', 15);
			
			var title = self.readAttrVal(node, 'title');
			var type = self.readAttrVal(node, 'type');
			var fontSize = self.readAttrVal(node, 'fontSize');
			var others = self.readAttrVal(node, 'others');
			
			if (type == 'label' || type == 'text') {
				self.addText(x, y, w, h, {title:title, type:type, fontSize:fontSize, others:others});
			} else if (type.indexOf('code') >= 0 || type == 'qrcode') {
				self.addBarCode(x, y, w, h, {title:title, type:type, others:others});
			} else if (type == 'image') {
				self.addImage(x, y, w, h, type, node);
			} else if (type == 'line') {
				var color = self.readAttrVal(node, 'color')||'';
				self.addLine(x, y, w, h, type, color);
			}
		}
	},

	//读取对象指定属性的值
	readAttrVal: function(element, attrName) {
		if (!element) return '';
		return element.getAttribute(attrName) || '';
	},
	
	//毫米转像素
	readAttrFloat: function(element, attrName) {
		var v = element.getAttribute(attrName) || '0';
		return parseFloat(parseInt(v)*this.PN).toFixed(2);
	},
	
	//添加字段标签，含label、field
	addFieldLabel: function(record) {
		var label = record.get('lab_field__field_title');
		var field = record.get('lab_field__field_code');
		field = '['+field+']';
		
		this.addText(20,20,120,24,{title:label,type:'label'},true);
		this.addText(160,20,120,24,{title:field,type:'text'},true);
	},
	
	//添加文字控件
	addText: function(x, y, w, h, cfg, isadd){
		var id = 'item'+this.compnum;
		
		var size = cfg.fontSize||'10';
		var others = cfg.others||'';
		var html = '<div id="'+id+'" class="fdes-fielditem x-unselectable" style="top:'+y+'px;left:'+x+'px;width:'+w+'px;height:'+h+'px;" '+
				   'title="'+cfg.title+'" type="'+cfg.type+'" fontSize="'+size+'" others="'+others+'">'+ cfg.title +'</div>';
		//console.log(html);
		if (isadd) {
			this.createCompHtml(id, html);
		} else {
			this.addCompHtml(id, html);
		}
	},
	
	//添加条码控件
	addBarCode: function(x, y, w, h, cfg, isadd){
		var others = cfg.others||'';
		var id = 'item'+this.compnum;
		var html = '<div id="'+id+'" class="fdes-fielditem x-unselectable" style="top:'+y+'px;left:'+x+'px;width:'+w+'px;height:'+h+'px;" title="'+
				   cfg.title+'" type="'+cfg.type+'" others="'+others+'"><img src="resources/images/code/'+cfg.type+'.jpg" width="100%" height="100%"/></div>';
		//console.log(html);
		if (isadd) {
			this.createCompHtml(id, html);
		} else {
			this.addCompHtml(id, html);
		}
	},
	
	//添加图片
	addImage: function(x, y, w, h, type, node, isadd) {
		var self = this;
		var id = 'item'+this.compnum;
		var path = self.readAttrVal(node, 'path');
		if (path.length == 0) path = 'resources/images/logo.png';
		var percent = self.readAttrVal(node, 'percent');
		if (percent.length == 0) percent = '100';
		var html = '<div id="'+id+'" class="fdes-fielditem x-unselectable" style="top:'+y+'px;left:'+x+'px;width:'+w+'px;height:'+h+'px;" path="'+path+'" percent="'+percent+'" type="'+			type+'"><img src="'+path+'" width="'+percent+'%" height="'+percent+'%"/></div>';
		//console.log(html);
		if (isadd) {
			this.createCompHtml(id, html);
		} else {
			this.addCompHtml(id, html);
		}
	},
	
	//添加线条
	addLine: function(x, y, w, h, type, color, isadd) {
		var self = this;
		var id = 'item'+this.compnum;
		color = color||'';
		var html = '<div id="'+id+'" class="fdes-fielditem x-unselectable" style="top:'+y+'px;left:'+x+'px;width:'+w+'px;height:'+h+'px;" color="'+color+'" type="'+
					type+'"></div>';
		//console.log(html);
		if (isadd) {
			this.createCompHtml(id, html);
		} else {
			this.addCompHtml(id, html);
		}
	},
	
	//把readDesign方法中的元素对象的html添加到全局变量中
	addCompHtml: function(id, html) {
		this.compnum++;
		if (this.compHtml == undefined) {
			this.compHtml = '';
		}
		
		//添加布局元素的html
		this.compHtml += html;
	},
	
	//直接添加一个控件
	createCompHtml: function(id, html) {
		var self = this;
		self.compnum++;
		
		//添加控件并取当前控件
		var curEl = self.parentEl.insertHtml('beforeEnd', html, true);
		//添加移动与缩放属性
		self.addCompDD(curEl);
		
		return curEl;
	},
	
	//删除控件
	deleteComp: function() {
		var self = this;
		if (self.selectDivs.length == 0) return;

		Ext.each(self.selectDivs, function(item){
			Ext.fly(item).remove();
		});
		self.selectDivs = [];
	},
	
	//把readDesign方法中的元素对象添加页面中
	insertCompHtml: function() {
		var self = this;
		self.parentEl.dom.innerHTML = self.compHtml;
		
		var selector = 'div.fdes-fielditem';
		//要添加true参数，否则取到的是fly共享对象
		self.parentEl.select(selector, true).each(self.addCompDD, self);
		
		//清除临时全局变量
		self.compHtml = null;
		delete self.compHtml;
	},
	
	//给布局元素添加移动、缩放特性
	addCompDD: function(el) {
		var self = this;
		//创建拖动对象；暂时不处理限制移动范围，因为当设计面板的scroll.top大于0时，创建的控件移动有问题。
		var dd = new Ext.dd.DD(el.dom.id);
        dd.setXConstraint(800, 800, 4);
        dd.setYConstraint(1500, 1500, 4);
		self.designDDs.push(dd);
		
		//点击时，才创建可缩放对象，提供性能
		el.on('click', function(){
			var curEl = this, hasRe = false;
			Ext.each(self.designResizes, function(item){
				if (item.getEl().id == curEl.id) {
					hasRe = true; return;
				}
			});
			//如果已创建了缩放对象，则不用创建了
			if (hasRe) return;
			
			var re = new Ext.Resizable(curEl, {minWidth:40, minHeight:22});
			self.designResizes.push(re);
		});
		
		//双击时显示属性设置
		el.on('dblclick', function(){self.updateProp(el);});
		//处理单个控件的选择、拖动事件
		self.initClickEl(el);
	},
	
	//构建设计信息的XML
	buildXML: function() {
		var self = this;
		var fn = function(v){
			var f = parseFloat(v/self.PN).toFixed(2);
			var i = Math.round(f);
			if (f == i) {
				return i;
			} else {
				return f;
			}
		};
		var width = fn(self.parentEl.dom.offsetWidth);
		var height = fn(self.parentEl.dom.offsetHeight);
		var titlex = self.parentEl.getAttribute('title');
		
		var childs = self.parentEl.query('div.fdes-fielditem');
		
		var xml = '';
		for (var i = 0, n = childs.length; i < n; i++) {
			var childEl = Ext.fly(childs[i]);
			
			var cx = fn(childEl.dom.offsetLeft);
			var cy = fn(childEl.dom.offsetTop);
			var cw = fn(childEl.dom.offsetWidth);
			var ch = fn(childEl.dom.offsetHeight);
			
			var title = childEl.getAttribute('title');
			var type = childEl.getAttribute('type');
			var fontSize = childEl.getAttribute('fontSize')||'';
			var others = childEl.getAttribute('others')||'';
			if (others.length > 0) others = ' others="'+others+'" ';
			var color = childEl.getAttribute('color')||'';
			if (color.length > 0) color = ' color="'+color+'" ';
			
			if (type == 'image') {
				var path = childEl.getAttribute('path');
				var percent = childEl.getAttribute('percent');
				xml += '<item type="'+type+'" path="'+path+'" x="'+cx+'" y="'+cy+'" width="'+cw+'" height="'+ch+'" percent="'+percent+'" />\r';
			} else {
				xml += '<item type="'+type+'" title="'+title+'" x="'+cx+'" y="'+cy+'" width="'+cw+'" height="'+ch+'" fontSize="'+fontSize+'"'+others+color+'/>\r';
			}
		}
		if (xml.length == 0) return ''
		
		var xmlcont = '<?xml version="1.0" encoding="utf-8"?>\r';
			xmlcont += '<page verno="1.0" width="'+width+'" height="'+height+'" title="'+titlex+'">\r';
			xmlcont += xml;
			xmlcont += '</page>';
		
		return xmlcont;
	},
	
	//保存设计文件
	saveXML: function(modelId, tmpxml) {
		var self = this;
		var xmlcont = tmpxml;
		if (!xmlcont) xmlcont = self.buildXML();
		
		var fn = function(v){
			return Math.round(parseFloat(v/self.PN));
		};
		var width = fn(self.parentEl.dom.offsetWidth);
		var height = fn(self.parentEl.dom.offsetHeight);
		
		var e = encodeURIComponent; //编码, 处理特殊字符
		var params = 'funid=lab_case&eventcode=savexml&modelid='+modelId;
			params += '&setxml='+ e(xmlcont) +'&colxml=&pagexml=&width='+width+'&height='+height;
		
		var dhcall = null;
		if (tmpxml) dhcall = function(){self.readXML(modelId);};
		
		//发送请求保存设计文件到数据库中
		Request.postRequest(params, dhcall);
	},
	
	//销毁临时对象
	destroy: function() {
		var self = this;
		Ext.each(self.designDDs, function(item){
			item.unreg();
			item = null;
		});
		Ext.each(self.designResizes, function(item){
			item.destroy(true);
			item = null;
		});
		self.designDDs = [];
		self.designResizes = [];
	},
	
	//显示源码，可以修改
	showXML: function(modelId) {
		var self = this;
		var xmlcont = self.buildXML();
					
		var tbar = new Ext.Toolbar({
			items:[
				{iconCls:'eb_save', text:jx.bus.text29, handler:function(){//'保存'
					var tmpxml = win.getComponent(0).getValue();
					self.saveXML(modelId, tmpxml);
				}},
				{iconCls:'eb_undo', text:jx.bus.text30, handler:function(){//'恢复'
					var field = win.getComponent(0);
					field.setValue(xmlcont);
				}}
			]
		});
		
		//创建对话框
		var win = new Ext.Window({
			title:jx.bus.text31,//'设计源码',
			layout:'fit',
			width:800,
			height:400,
			resizable: true,
			modal: true,
			autoScroll: true,
			closeAction: 'close',
			tbar:tbar,
			items:[{
				xtype:'textarea',
				selectOnFocus:false,
				value:xmlcont
			}]
		});
		win.show();
	},
	
	//显示控件大小
	showItemSize: function(el) {
		var self = this;
		var fn = function(v){
			var f = parseFloat(v/self.PN).toFixed(2);
			var i = Math.round(f);
			if (f == i) {
				return i;
			} else {
				return f;
			}
		};
		
		var cx = fn(el.dom.offsetLeft);
		var cy = fn(el.dom.offsetTop);
		var cw = fn(el.dom.offsetWidth);
		var ch = fn(el.dom.offsetHeight);
		
		self.statusBar.dom.innerHTML = ' x='+cx+'mm  y='+cy+'mm  width='+cw+'mm  height='+ch+'mm';
	},

	/**
	 * 修改属性，打开修改控件属性的对话框
	 * 只有formitem与fielditem可以设置属性，formitem是设置fieldset属性。
	 **/
	updateProp: function(curel) {
		var self = this;
		var curdom = curel.dom;
		var winTitle = '设置属性';
		var type = self.readAttrVal(curdom, 'type');
		var propSrc = {
				type: type,
				width: parseInt(curdom.offsetWidth/self.PN),
				height: parseInt(curdom.offsetHeight/self.PN),
				title: self.readAttrVal(curdom, 'title')
			};
		if (type == 'text' || type == 'label') {
			propSrc.fontSize = self.readAttrVal(curdom, 'fontSize');
		}
		if (type == 'image') {
			propSrc.path = self.readAttrVal(curdom, 'path');
			propSrc.percent = self.readAttrVal(curdom, 'percent');
		}
		if (type == 'line') {
			propSrc.color = self.readAttrVal(curdom, 'color');
		}
		if (type == 'text' || type == 'label' || type.indexOf('code') >= 0) {
			propSrc.others = self.readAttrVal(curdom, 'others');
		}
		var iscard = curel.hasClass('fdes-card');
		if (iscard) delete propSrc.type;
		
		//创建属性表格
		var propsGrid = new Ext.grid.PropertyGrid({
			border: false,
			width: 300,
			source: propSrc
		});
		propsGrid.getColumnModel().setColumnWidth(0, 30);

		//创建对话框
		var win = new Ext.Window({
			title:winTitle,
			layout:'fit',
			width:300,
			height:350,
			modal:true,
			closeAction:'close',
			items:[propsGrid],

			buttons: [{
				text:jx.base.ok,	//'确定',
				handler:function(){
					var src = propsGrid.getSource();
					
					curdom.setAttribute('title', src.title);
					Ext.fly(curdom).setWidth(src.width*self.PN);
					Ext.fly(curdom).setHeight(src.height*self.PN);
					if (!iscard) curdom.setAttribute('type', src.type);
					curdom.setAttribute('others', src.others||'');
					if (type == 'image') {
						curdom.setAttribute('path', src.path);
						curdom.setAttribute('percent', src.percent);
					} 
					if (type == 'line') {
						curdom.setAttribute('color', src.color);
					}
					if (type == 'text' || type == 'label') {
						curdom.setAttribute('fontSize', src.fontSize);
					}
					
					win.close();
				}
			},{
				text:jx.base.cancel,	//'取消',
				handler:function(){win.close();}
			}]
		});
		win.show();
	},
	
	//===========================下面是一个独立的类，为了调用方便放到一个文件中了===================================
	//使用了上面的参数有：
	//parentEl -- 作为容器对象
	//findChilds -- 取指定控件位置内的控件
	/**
	 * 当前批量选择的控件，是dom对象数组
	 **/
	selectDivs: [],
	
	/**
	 * 记录是否开始多选控件的状态，
	 * 在mousemove，并按住Ctrl键时，设置值为true，mouseup时设置为false
	 **/
	selectDowned: false,
	
	/**
	 * 记录开始多选时的鼠标位置
	 **/
	selectOldXY: [],
	
	/**
	 * 记录是否开始拖动选择的状态，
	 * 在mousemove，并按住Ctrl键时，设置值为true，mouseup时设置为false
	 **/
	moveDowned: false,
	
	/**
	 * 当前点击拖动的控件，是Element对象
	 **/
	moveDownEl: null,
	
	/**
	 * 记录开始拖动时的鼠标位置
	 **/
	moveOldX: 0,
	moveOldY: 0,
	
	/**
	 * 记录批量选择的控件外围位置，{x, y, width, height}
	 **/
	moreDivPos: null,
	
	/**
	 * 初始化，给容器添加事件
	 **/
	initDd: function() {
		var self = this;
		//添加批量选择控件的事件
		self.parentEl.on('mousedown', self.moreMouseDown, self);
		self.parentEl.on('mouseup', self.moreMouseUp, self);
		self.parentEl.on('mousemove', self.moreMouseMove, self);
		//如果是点击画布，则清除控件选择
		/*self.parentEl.on('click', function(e, t){
			if (e.ctrlKey) return;
			var el = Ext.fly(t);
			if (!el.hasClass('fdes-formitem') && 
				!el.hasClass('fdes-columnitem') && 
				!el.hasClass('fdes-fielditem')) {
				//销毁标志DIV，有时误操作没有销毁
				var flagEl = self.parentEl.first('#select_flag_div');
				if (flagEl) flagEl.remove();
				//清除选择的对象
				self.clearSelectDivs();
			}
		});*/
	},
	/******************************下面是处理选择多个控件的操作**********************************/
	/**
	 * private
	 * 开始框选控件：创建框选标志DIV，要求按住CTRL键
	 **/
	moreMouseDown: function(e) {
		var self = this;
		//必须要按ctrl键才有效
		//if (!e.ctrlKey) return;	//简化处理，不需要按CTRL键
		self.parentEl.select('#select_flag_div').remove();
		self.selectDowned = true;
		//取消文本选择
		if (Ext.isIE) {
			self.parentEl.dom.onselectstart = function(){return false;};
		}
		
		var xy = e.getXY();
		//鼠标位置必须去掉容器控件的位置
		var pxy = self.parentEl.getXY();
		var x = xy[0] - pxy[0];
		var y = xy[1] - pxy[1];
		//保存鼠标点击的位置
		self.selectOldXY = [x, y];
		//创建鼠标框选标志DIV
		self.parentEl.insertHtml('afterBegin', 
		'<div id="select_flag_div" class="fdes-selectdiv" style="left:'+ x +'px;top:'+ y +'px;"></div>');
	},
	
	/**
	 * private
	 * 结束框选控件：添加选择的控件对象；销毁框选标志DIV
	 **/
	moreMouseUp: function(e) {
		var self = this;
		if (!self.selectDowned) return;
		//清除状态信息
		self.clearSelectDivs();
		if (Ext.isIE) {
			self.parentEl.dom.onselectstart = null;
		}
		
		//取框选标志DIV
		var flagEl = self.parentEl.first('#select_flag_div');
		//取选择的控件
		var divs = self.findChilds(flagEl, 'div.fdes-fielditem, div.fdes-columnitem, div.fdes-formitem');
		//标志选择的控件
		self.flagSelectDivs(divs);
		
		//销毁标志
		flagEl.remove();
	},
	
	/**
	 * private
	 * 调整框选标志的大小
	 **/
	moreMouseMove: function(e) {
		var self = this;
		if (!self.selectDowned) return;
		//取框选标志DIV
		var flagEl = self.parentEl.first('#select_flag_div');
		var xy = e.getXY();
		var pxy = self.parentEl.getXY();
		//取当前鼠标相对位置、与鼠标点击时的位置
		var x = xy[0] - pxy[0], y = xy[1] - pxy[1];
		var ox = self.selectOldXY[0], oy = self.selectOldXY[1];
		
		//取绝对值，设置框选对象的宽与高
		var w = Math.abs(x - ox);
		var h = Math.abs(y - oy);
		flagEl.setWidth(w);
		flagEl.setHeight(h);
		
		//设置选择的区域
		if (x > ox && y < oy) {			//表示鼠标向上移动
			flagEl.setTop(y);
		} else if (x < ox && y < oy) {	//表示鼠标向左上移动
			flagEl.setTop(y);
			flagEl.setLeft(x);
		} else if (x < ox && y > oy) {	//表示鼠标向左移动
			flagEl.setLeft(x);
		}
	},
	
	/**
	 * 设置选择对象的样式
	 * selected -- true 表示选择，false 表示取消选择
	 **/
	selectCss: function(selected) {
		var divs = this.selectDivs;
		for (var i = 0, n = divs.length; i < n; i++) {
			var childEl = Ext.fly(divs[i]);
			
			if (selected) {
				childEl.addClass('fdes-selectcomp');
			} else {
				childEl.removeClass('fdes-selectcomp');
			}
		}
	},
	
	/**
	 * public
	 * 标志当前控件为选择的控件
	 **/
	flagSelectDivs: function(divs) {
		if (divs == null || divs.length == 0) return;
		
		var self = this;
		//清除原来的控件
		self.selectCss(false);
	
		//标志新的选择的控件
		self.selectDivs = divs;
		//标志选择的字段样式
		self.selectCss(true);
		//保存选择的控件初始位置
		self.selectXY();
		//保存选择的控件的外围位置
		self.moreDivPos = self.getMoreDivPos();
	},
	
	/**
	 * public
	 * 清除选择控件的标记
	 **/
	clearSelectDivs: function() {
		var self = this;
		self.selectCss(false);
		self.selectDivs = [];
		self.moreDivPos = null;
		self.selectDowned = false;
	},
	
	/**
	 * public
	 * 判断当前选择的元素是否在批量选择元素中
	 * curDiv -- 当前选择当个元素
	 **/
	isSelectDiv: function(curDiv) {
		var divs = this.selectDivs;
		for (var i = 0, n = divs.length; i < n; i++) {
			var div = divs[i];
			if (curDiv.id == div.id) return true;
		}
		return false;
	},
	
	/**
	 * private
	 * 保存当前选择的元素初始XY
	 **/
	selectXY: function() {
		var self = this;
		var divs = self.selectDivs;
		for (var i = 0, n = divs.length; i < n; i++) {
			self.saveOldXY(divs[i]);
		}
	},
	
	/**
	 * private
	 * 保存一个选择的元素初始XY，考虑了滚动条的位置
	 **/
	saveOldXY: function(div) {
		var childEl = Ext.fly(div);
		//要处理滚动条的距离
		var scroll = this.parentEl.getScroll();
		if (scroll.top != 0) {
			var oldX = childEl.getX() + scroll.left;
			var oldY = childEl.getY() + scroll.top;
			div.oldXY = [oldX, oldY];
		} else {
			div.oldXY = childEl.getXY();
		}
	},
	
	/******************************下面是处理选择单个控件的操作**********************************/
	/**
	 * public
	 * 初始化控件事件。下面的方法必须放到新的function中，否则会报错，暂时还未查到原因
	 *
	 * 移动控件有两种方法：
	 * 1、记录当前选择的控件，根据控件移动位置确定其它控件的移动位置，现在采用此方法：问题是点击的控件与其它移动不同步
	 * 2、记录当前鼠标点击的位置，根据鼠标移动位置确定其它控件的移动位置，问题有：要取消dd移动设置，且不能处理移动步长设置
	 **/
	initClickEl: function(clickEl) {
		var self = this;
		clickEl.on('mousedown', function(e){self.oneMouseDown(clickEl, e);});
		clickEl.on('mousemove', function(e){self.oneMouseMove(e);});
		clickEl.on('mouseup', function(e){self.oneMouseUp(e);});
	},
	
	/**
	 * public
	 * 单击容器中的控件，并给控件标志
	 **/
	oneMouseDown: function(clickEl, e) {
		var self = this;
		
		//判断当前点击的控件是否在已选控件中
		var isMore = self.isSelectDiv(clickEl.dom, self.selectDivs);
		
		//是已选控件：如果按住CTRL，则取消选择，否则标志开始移动
		if (isMore) {
			if (e.ctrlKey) {
				clickEl.removeClass('fdes-selectcomp');
				self.selectDivs.remove(clickEl.dom);
				//重新计算选择控件的外围位置
				self.moreDivPos = self.getMoreDivPos();
			} else {
				//如果没有按住CTRL键，则标志开始拖动
				if (self.selectDivs.length > 1) {
					self.moveOldX = clickEl.getX();
					self.moveOldY = clickEl.getY();
					self.moveDowned = true;
					self.moveDownEl = clickEl;
				}
			}
		} else {
		//不是已选控件：如果按住CTRL，则添加为已选，否则清除原已选标志新已选
			self.oneClickEl(clickEl, e);
		}
	},
	
	/**
	 * public
	 * 处理容器中控件的鼠标移动事件
	 **/
	oneMouseMove: function(e) {
		var self = this;
		if (!self.moveDowned) return;
		var scroll = self.parentEl.getScroll();
		//取鼠标移动的间隔值，要考虑滚动条的位置
		var curEl = self.moveDownEl;
		var dx = curEl.getX() - self.moveOldX - scroll.left;
		var dy = curEl.getY() - self.moveOldY - scroll.top;
		
		//判断控件是否超过边框
		var vx = self.validMoreDivX(dx);
		var vy = self.validMoreDivY(dy);
		
		//批量选择的控件都要移动
		for (var i = 0, n = self.selectDivs.length; i < n; i++) {
			var item = self.selectDivs[i];
			var itemEl = Ext.fly(item);
			//oldXY是自定义属性，在批量选择控件时设置
			var oldXY = item.oldXY;
			
			//如果选择框的左右边都在容器范围内，则可以调整X值
			if (vx) {
				itemEl.setX(oldXY[0] + dx);
			}
			//如果选择框的上下边都在容器范围内，则可以调整Y值
			if (vy) {
				itemEl.setY(oldXY[1] + dy);
			}
		}
	},
	
	/**
	 * public
	 * 处理容器中控件的鼠标提起事件
	 **/
	oneMouseUp: function(e) {
		var self = this;
		if (!self.moveDowned) return;
		
		//重新设置选择控件的原位置与边框大小
		self.selectXY();
		self.moreDivPos = self.getMoreDivPos();
		
		//清除状态值
		self.moveOldX = 0;
		self.moveOldY = 0;
		self.moveDownEl = null;
		self.moveDowned = false;
	},
	
	/**
	 * private
	 * 单击容器中的控件，如果没有按CTRL，则值保留当前控件为已选
	 **/
	oneClickEl: function(clickEl, e) {
		var self = this;
		if (!e.ctrlKey) {
			self.clearSelectDivs();
		}
		
		//添加到选择的控件中
		var len = self.selectDivs.length;
		self.selectDivs[len] = clickEl.dom;
		clickEl.addClass('fdes-selectcomp');
		
		//保存控件初始位置
		self.saveOldXY(clickEl.dom);
		//重新计算选择控件的外围位置
		self.moreDivPos = self.getMoreDivPos();
		
		//显示控件大小在状态栏
		self.showItemSize(clickEl);
	},
	//=======================下面三个方法是处理多选控件移动时不能超出边框=====================
	/**
	 * private
	 * 取批量控件的位置数组值，返回[x, y, width, height]
	 **/
	getMoreDivPos: function() {
		var self = this;
		//取最左部控件的left值，取最小值
		var minx = 1000000;
		for (var i = 0, n = self.selectDivs.length; i < n; i++) {
			var itemEl = Ext.fly(self.selectDivs[i]);
			
			if (itemEl.getX() < minx) minx = itemEl.getX();
		}
		//取最上部控件的top值，取最小值
		var miny = 1000000;
		for (var i = 0, n = self.selectDivs.length; i < n; i++) {
			var itemEl = Ext.fly(self.selectDivs[i]);
			
			if (itemEl.getY() < miny) miny = itemEl.getY();
		}
		//取最右部控件的right边框位置，取最大值
		var maxr = 0;
		for (var i = 0, n = self.selectDivs.length; i < n; i++) {
			var itemEl = Ext.fly(self.selectDivs[i]);
			
			var right = itemEl.getX() + itemEl.getWidth();
			if (right > maxr) maxr = right;
		}
		//取最下部控件的bottom边框位置，取最大值
		var maxb = 0;
		for (var i = 0, n = self.selectDivs.length; i < n; i++) {
			var itemEl = Ext.fly(self.selectDivs[i]);
			
			var bottom = itemEl.getY() + itemEl.getHeight();
			if (bottom > maxb) maxb = bottom;
		}
		
		var width = maxr-minx;
		var height = maxb-miny;
		var pxy = self.parentEl.getXY();
		var x = minx - pxy[0];
		var y = miny - pxy[1];
		//测试边框计算是否准确
		//self.parentEl.insertHtml('afterBegin', 
		//'<div id="select_flag_div1" class="fdes-selectdiv" style="left:'+ x +'px;top:'+ y +'px;width:'+ width +'px;height:'+ height +'px;"></div>');
		
		return {x:x, y:y, width:width, height:height};
	},
	
	/**
	 * private
	 * 检查批量控件移动的X值是否在容器内
	 **/
	validMoreDivX: function(movex) {
		var self = this;
		//取容器的x与width
		var px = 0;//self.parentEl.getX();
		var pw = self.parentEl.getWidth();
		
		//取批量控件边框的x与width
		var sx = self.moreDivPos.x;
		var sw = self.moreDivPos.width;
		
		//说明左边超界
		if ((sx + movex) < px) return false;
		//说明右边超界
		if ((sx + sw + movex) > (px + pw)) return false;
		
		return true;
	},
	
	/**
	 * private
	 * 检查批量控件移动的Y值是否在容器内
	 **/
	validMoreDivY: function(movey) {
		var self = this;
		//取容器的y与height
		var py = 0;//self.parentEl.getY();
		var ph = self.parentEl.getHeight() - 20;
		
		//取批量控件边框的y与height
		var sy = self.moreDivPos.y;
		var sh = self.moreDivPos.height;
		
		//说明上边超界
		//if ((sy + movey) < py) return false; //modify by tony.tan, 方面调整多字段界面。
		//说明下边超界
		//if ((sy + sh + movey) > (py + ph)) return false; //modify by tony.tan, 方面调整多字段界面。
		
		return true;
	}
	
};